package com.example.exercise.rule;

import com.example.exercise.common.Pojo;
import org.jeasy.rules.api.Facts;
import org.jeasy.rules.api.Rule;
import org.jeasy.rules.api.Rules;
import org.jeasy.rules.api.RulesEngine;
import org.jeasy.rules.core.DefaultRulesEngine;
import org.jeasy.rules.mvel.MVELRule;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class EasyRulesUtils {
    private static final Logger LOGGER = LoggerFactory.getLogger(EasyRulesUtils.class);

    public static <T extends Pojo> Boolean match(T data, String ruleStr){
        String ruleExp = DataInit.preHandler(data, ruleStr);
        if(ruleExp == null || "".equals(ruleExp)){
            LOGGER.error("规则表达式错误");
            return false;
        }

        Map<String, Object> map = DataInit.dataToMap(data, "yyyy-MM-dd");
        map.put("clazzDateFormat", new SimpleDateFormat("yyyy-MM-dd"));
        String finalRule = DataInit.transExpWithSubDateField(data, ruleExp);
        Facts facts = mapToFacts(data);
        return new MVELRule().when(finalRule).evaluate(facts);
    }

    public static <T extends Pojo> List<T> match(List<T> dataList, String ruleStr){
        if(dataList.isEmpty()){
            return dataList;
        }
        T data = dataList.get(0);
        String ruleExp = DataInit.preHandler(data, ruleStr);
        if(ruleExp == null || "".equals(ruleExp)){
            LOGGER.error("规则表达式错误，返回所有数据");
            return dataList;
        }

        Rule rule = new MVELRule().when(ruleExp);
        Rules rules = new Rules();
        rules.register(rule);
        RulesEngine rulesEngine = new DefaultRulesEngine();
        List<T> list = new ArrayList<>();
        for (T data1 : dataList) {
            Facts facts = mapToFacts(data1);
            if(rulesEngine.check(rules, facts).get(rule)){
                list.add(data1);
            }
        }
        return list;
    }

    public static <T extends Pojo> List<Object> calculate(T data, String ruleStr){
        String ruleExp = DataInit.preHandler(data, ruleStr);
        if(ruleExp == null || "".equals(ruleExp)){
            LOGGER.error("规则表达式错误");
            return null;
        }

        Rule rule = new MVELRule().then(ruleExp);
        Rules rules = new Rules();
        rules.register(rule);
        RulesEngine rulesEngine = new DefaultRulesEngine();
        List<Object> results =  new ArrayList<>();
        Facts facts = mapToFacts(data);
        facts.put("results", results);
        rulesEngine.fire(rules, facts);
        return results;
    }

    public static <T extends Pojo> List<Object> calculate(List<T> dataList, String ruleStr){
        if(dataList.isEmpty()){
            return new ArrayList<>();
        }
        T data = dataList.get(0);
        String ruleExp = DataInit.preHandler(data, ruleStr);
        if(ruleExp == null || "".equals(ruleExp)){
            LOGGER.error("规则表达式错误，返回所有数据");
            return new ArrayList<>();
        }
        Rule rule = new MVELRule().then(ruleExp);
        Rules rules = new Rules();
        rules.register(rule);
        RulesEngine rulesEngine = new DefaultRulesEngine();
        List<Object> list = new ArrayList<>();
        for (T data1 : dataList) {
            List<Object> results =  new ArrayList<>();
            Facts facts = mapToFacts(data1);
            facts.put("results", results);
            rulesEngine.fire(rules, facts);
            list.addAll(results);
        }
        return list;
    }

    private static <T extends Pojo> Facts mapToFacts(T data){
        Facts fact = new Facts();
        Map<String, Object> map = DataInit.dataToMap(data, "yyyy-MM-dd");
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            fact.put(entry.getKey(), entry.getValue());
        }
        return fact;
    }
}
